#include "AggregatedFunctionBox.h"
#include "../../runtime/AutomaticBoxCreatorRegistration.h"
#include <limits>

namespace jm4bbx {
	const  outType AggregatedFunctionBox::OUT_ARC = outType(0);

	const  inType AggregatedFunctionBox::IN_ARC = inType(0);

	const  columnType AggregatedFunctionBox::OUTPUT_COLUMN = columnType(1);

	const  columnType AggregatedFunctionBox::INPUT_COLUMN = columnType(0);

	const  groupType AggregatedFunctionBox::OUTPUT_GROUP = groupType(1);

	const  groupType AggregatedFunctionBox::INPUT_GROUP = groupType(0);


	class SumBox : public AggregatedFunctionBox {
	public:
		SumBox(const BoxParamPack& p) : AggregatedFunctionBox(p) { }

		virtual void initAggregatedValue() { sum_ = 0;}
		virtual void aggregateValue(int value) { sum_ += value; }
		virtual void outputAggregatedValue() { addOutputData(sum_); }

	private:
		int sum_;
	};
	REGISTER_BOX_TO_RUNTIME_BASE(SUM_INTEGER, SumBox);

	class MinBox : public AggregatedFunctionBox {
	public:
		MinBox(const BoxParamPack& p) : AggregatedFunctionBox(p) { }

		virtual void initAggregatedValue() { min_ = std::numeric_limits<int>::max();}
		virtual void aggregateValue(int value) { if (value < min_) min_ = value; }
		virtual void outputAggregatedValue() { addOutputData(min_); }

	private:
		int min_;
	};
	REGISTER_BOX_TO_RUNTIME_BASE(MIN_INTEGER, MinBox);


	class MaxBox : public AggregatedFunctionBox {
	public:
		MaxBox(const BoxParamPack& p) : AggregatedFunctionBox(p) { }

		virtual void initAggregatedValue() { max_ = std::numeric_limits<int>::min();}
		virtual void aggregateValue(int value) { if (value > max_) max_ = value; }
		virtual void outputAggregatedValue() { addOutputData(max_); }

	private:
		int max_;
	};
	REGISTER_BOX_TO_RUNTIME_BASE(MAX_INTEGER, MaxBox);

	class AvgBox : public AggregatedFunctionBox {
	public:
		AvgBox(const BoxParamPack& p) : AggregatedFunctionBox(p) { }

		virtual void initAggregatedValue() { sum_ = count_ = 0;}
		virtual void aggregateValue(int value) { sum_ += value; ++count_; }
		virtual void outputAggregatedValue() { 
			addOutputData(sum_); 
			addOutputData(count_); 
		}

	private:
		int sum_;
		int count_;
	};
	REGISTER_BOX_TO_RUNTIME_BASE(AVG_INTEGER, AvgBox);

} // namespace jm4bbx
